home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / lfs / lfsBlockIO.c < prev    next >
C/C++ Source or Header  |  1991-06-29  |  8KB  |  256 lines

  1. /* 
  2.  * lfsBlockIO.c --
  3.  *
  4.  *    Routines for handling block allocate and access of files in a 
  5.  *    LFS file system. This routines are used by the cache code or
  6.  *    read and allocate files.
  7.  *
  8.  * Copyright 1989 Regents of the University of California
  9.  * Permission to use, copy, modify, and distribute this
  10.  * software and its documentation for any purpose and without
  11.  * fee is hereby granted, provided that the above copyright
  12.  * notice appear in all copies.  The University of California
  13.  * makes no representations about the suitability of this
  14.  * software for any purpose.  It is provided "as is" without
  15.  * express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /sprite/src/kernel/lfs/RCS/lfsBlockIO.c,v 1.7 91/06/29 17:01:02 mendel Exp $ SPRITE (Berkeley)";
  20. #endif /* not lint */
  21.  
  22. #include <sprite.h>
  23. #include <lfs.h>
  24. #include <lfsInt.h>
  25. #include <fs.h>
  26. #include <fsutil.h>
  27. #include <fsio.h>
  28. #include <fsioFile.h>
  29. #include <fslcl.h>
  30. #include <fscache.h>
  31. #include <fsdm.h>
  32. #include <fsStat.h>
  33.  
  34.  
  35.  
  36. /*
  37.  *----------------------------------------------------------------------
  38.  *
  39.  * Lfs_FileBlockRead --
  40.  *
  41.  *    Read in a cache block.  This routine uses the files'
  42.  *    indexing structure to locate the file block on disk.
  43.  *    This always attempts to read in a full block, but will read
  44.  *    less if at the last block and it isn't full.  In this case,
  45.  *    the remainder of the cache block is zero-filled.
  46.  *
  47.  * Results:
  48.  *    The results of the disk read.
  49.  *
  50.  * Side effects:
  51.  *    The blockPtr->blockSize is modified to
  52.  *    reflect how much data was actually read in.  The unused part
  53.  *    of the block is filled with zeroes so that higher levels can
  54.  *    always assume the block has good stuff in all parts of it.
  55.  *
  56.  *----------------------------------------------------------------------
  57.  */
  58. ReturnStatus
  59. Lfs_FileBlockRead(domainPtr, handlePtr, blockPtr)
  60.     Fsdm_Domain        *domainPtr;    /* Domain of file. */
  61.     register Fsio_FileIOHandle *handlePtr;    /* Handle on a local file. */
  62.     Fscache_Block       *blockPtr;      /* Cache block to read in.  This assumes
  63.                                          * the blockNum, blockAddr (buffer area)
  64.                                          * and blockSize are set.  This modifies
  65.                                          * blockSize if less bytes were read
  66.                                          * because of EOF. */
  67. {
  68.     Lfs    *lfsPtr = LfsFromDomainPtr(domainPtr);
  69.     register    Fsdm_FileDescriptor *descPtr;
  70.     register             offset;
  71.     register int         numBytes;
  72.     LfsDiskAddr            diskAddress;
  73.     ReturnStatus         status;
  74.  
  75.     LFS_STATS_INC(lfsPtr->stats.blockio.reads);
  76.     status = SUCCESS;
  77.     blockPtr->blockSize = 0;
  78.     numBytes = FS_BLOCK_SIZE;
  79.     offset = blockPtr->blockNum * FS_BLOCK_SIZE;
  80.  
  81.     /*
  82.      * Is a logical file read. Round the size down to the actual
  83.      * last byte in the file.
  84.      */
  85.     descPtr = handlePtr->descPtr;
  86.     if (offset > descPtr->lastByte) {
  87.     goto exit;
  88.     } else if (offset + numBytes - 1 > descPtr->lastByte) {
  89.     numBytes = descPtr->lastByte - offset + 1;
  90.     }
  91.  
  92.     status = LfsFile_GetIndex(handlePtr, offset / FS_BLOCK_SIZE, 0,
  93.                  &diskAddress);
  94.     if (status != SUCCESS) {
  95.     printf("Lfs_FileBlockRead: Could not setup indexing\n");
  96.     goto exit;
  97.     }
  98.  
  99.     if (!LfsIsNilDiskAddr(diskAddress)) {
  100.     /*
  101.      * Read in the block.  Specify the device, the fragment index,
  102.      * the number of fragments, and the memory buffer.
  103.      */
  104.     int    ioSize = 
  105.         LfsBlocksToBytes(lfsPtr, LfsBytesToBlocks(lfsPtr, numBytes));
  106.     LfsCheckRead(lfsPtr, diskAddress, numBytes);
  107.  
  108.     status = LfsReadBytes(lfsPtr, diskAddress, ioSize, blockPtr->blockAddr);
  109.     LFS_STATS_ADD(lfsPtr->stats.blockio.bytesReads, ioSize);
  110.     } else {
  111.     /*
  112.      * Zero fill the block.  We're in a 'hole' in the file.
  113.      */
  114. #ifdef STATS
  115.     fs_Stats.blockCache.readZeroFills++;
  116. #endif
  117.     bzero(blockPtr->blockAddr, numBytes);
  118.     }
  119. #ifdef STATS
  120.     Fs_StatAdd(numBytes, fs_Stats.gen.fileBytesRead, 
  121.         fs_Stats.gen.fileReadOverflow);
  122. #ifdef SOSP91
  123.     if (proc_RunningProcesses[0] != (Proc_ControlBlock *) NIL) {
  124.     if ((proc_RunningProcesses[0]->state == PROC_MIGRATED) ||
  125.         (proc_RunningProcesses[0]->genFlags &
  126.         (PROC_FOREIGN | PROC_MIGRATING))) {
  127.         Fs_StatAdd(numBytes, fs_SospMigStats.gen.fileBytesRead, 
  128.             fs_SospMigStats.gen.fileReadOverflow);
  129.     }
  130.     }
  131. #endif SOSP91
  132. #endif
  133. exit:
  134.     /*
  135.      * Define the block size and error fill leftover space.
  136.      */
  137.     if (status == SUCCESS) {
  138.     blockPtr->blockSize = numBytes;
  139.     }
  140.     if (blockPtr->blockSize < FS_BLOCK_SIZE) {
  141. #ifdef STATS
  142.     fs_Stats.blockCache.readZeroFills++;
  143. #endif
  144.     bzero(blockPtr->blockAddr + blockPtr->blockSize,
  145.         FS_BLOCK_SIZE - blockPtr->blockSize);
  146.     }
  147.     return(status);
  148. }
  149.  
  150. /*
  151.  *----------------------------------------------------------------------
  152.  *
  153.  * Lfs_FileBlockWrite --
  154.  *
  155.  *      Write out a cache block.  Since lfs maintains its own cache
  156.  *    write back mechanism, this routines should never be called.
  157.  *
  158.  * Results:
  159.  *      FAILURE
  160.  *
  161.  * Side effects:
  162.  *      It panic's.
  163.  *
  164.  *----------------------------------------------------------------------
  165.  */
  166. /*ARGSUSED*/
  167. ReturnStatus
  168. Lfs_FileBlockWrite(domainPtr, handlePtr, blockPtr)
  169.     Fsdm_Domain     *domainPtr;
  170.     Fsio_FileIOHandle *handlePtr;    /* I/O handle for the file. */
  171.     Fscache_Block *blockPtr;    /* Cache block to write out. */
  172. {
  173.     panic("Lfs_FileBlockWrite called\n");
  174.     return FAILURE;
  175. }
  176.  
  177.  
  178. /*
  179.  *----------------------------------------------------------------------
  180.  *
  181.  * Lfs_BlockAllocate --
  182.  *
  183.  *      Allocate disk space for the given file.  This routine only allocates
  184.  *      one block beginning at offset and going for numBytes. 
  185.  *
  186.  * Results:
  187.  *    SUCCESS or FS_NO_DISK_SPACE
  188.  *      
  189.  *
  190.  * Side effects:
  191.  *      The file descriptor is modified to contain pointers to the allocated
  192.  *      blocks.  Also *blockAddrPtr is set to the block that was allocated.
  193.  *
  194.  *----------------------------------------------------------------------
  195.  */
  196. ReturnStatus
  197. Lfs_BlockAllocate(domainPtr, handlePtr, offset, numBytes, flags, blockAddrPtr,
  198.         newBlockPtr)
  199.     Fsdm_Domain        *domainPtr;    /* Domain of file. */
  200.     register Fsio_FileIOHandle *handlePtr;    /* Local file handle. */
  201.     int         offset;        /* Offset to allocate at. */
  202.     int         numBytes;    /* Number of bytes to allocate. */
  203.     int            flags;        /* FSCACHE_DONT_BLOCK */
  204.     int            *blockAddrPtr;     /* Disk address of block allocated. */
  205.     Boolean        *newBlockPtr;    /* TRUE if there was no block allocated
  206.                      * before. */
  207. {
  208.     Lfs    *lfsPtr = LfsFromDomainPtr(domainPtr);
  209.     int    newLastByte;
  210.     ReturnStatus status;
  211.     Boolean    dirty = FALSE;
  212.     register    Fsdm_FileDescriptor *descPtr;
  213.  
  214.     LFS_STATS_INC(lfsPtr->stats.blockio.allocs);
  215.     /*
  216.      * Block allocates while checkpoints are active. This ensure that
  217.      * the LFS cache backend will be able to clean all LFS files from the
  218.      * cache. We only need worry about files, directory updates get stopped by
  219.      * the dirlog mechanism. In fact, waiting for a checkpoint for a 
  220.      * directory block allocate causes a possible deadlock because the
  221.      * checkpoint waits for directory operations to finish. We also
  222.      * use this mechanism to keep from filling up the cache with blocks
  223.      * that we can't write out.
  224.      */
  225.     descPtr = handlePtr->descPtr;
  226.     if (descPtr->fileType != FS_DIRECTORY) {
  227.     LfsWaitForCleanSegments(lfsPtr);
  228.     } 
  229.     /*
  230.      * First check to see if we can just allocate the bytes.
  231.      */
  232.     newLastByte = offset + numBytes - 1; 
  233.     *blockAddrPtr = FSDM_NIL_INDEX;
  234.     status = LfsFile_GrowBlock(lfsPtr, handlePtr, offset, numBytes);
  235.     if (status == SUCCESS) {
  236.     *newBlockPtr = FALSE;
  237.     *blockAddrPtr = offset / FS_BLOCK_SIZE;
  238.      if (newLastByte > descPtr->lastByte) {
  239.         descPtr->lastByte = newLastByte;
  240.         dirty = TRUE;
  241.      }
  242.     } 
  243.     if ((status == SUCCESS) && descPtr->firstByte == -1 && 
  244.     ((descPtr->fileType == FS_NAMED_PIPE) ||
  245.      (descPtr->fileType == FS_PSEUDO_DEV) ||
  246.      (descPtr->fileType == FS_XTRA_FILE))) {
  247.     descPtr->firstByte = 0;
  248.     dirty = TRUE;
  249.     }
  250.     if (dirty) { 
  251.     descPtr->descModifyTime = Fsutil_TimeInSeconds();
  252.     descPtr->flags |= FSDM_FD_SIZE_DIRTY;
  253.     } 
  254.     return(status);
  255. }
  256.